﻿#include "stdafx.h"
#include "stats.h"

GetInfo::GetInfo()
{
	IWbemLocator *pLoc = NULL;
	IWbemServices *pSvc = NULL;
	IEnumWbemClassObject* pEnumerator = NULL;
	ULONG uReturn = 0;
	_debug = false;
	// 
	GetInfo::InitCOM();
	GetInfo::SetSecurityLevels();
	GetInfo::InitLocatorWMI();
	GetInfo::ConnectToRoot(L"ROOT\\CIMV2");
	GetInfo::SetProxyLevel();
	

}
GetInfo::~GetInfo()
{
	GetInfo::Cleanup();
}

bool GetInfo::Debug()
{
	_debug = !_debug;
	return _debug;
}


int GetInfo::InitCOM()
{

    hres =  CoInitializeEx(0, COINIT_MULTITHREADED); 
    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Failed to initialize COM library. Error code = 0x" 
            << hex << hres << endl;
		return 1;  
		} else return 1;
                        // Program has failed.
    } else return 0;
}

int GetInfo::SetSecurityLevels()
{
	
    hres =  CoInitializeSecurity(
        NULL, 
        -1,                          // COM authentication
        NULL,                        // Authentication services
        NULL,                        // Reserved
        RPC_C_AUTHN_LEVEL_DEFAULT,   // Default authentication 
        RPC_C_IMP_LEVEL_IMPERSONATE, // Default Impersonation  
        NULL,                        // Authentication info
        EOAC_NONE,                   // Additional capabilities 
        NULL                         // Reserved
        );

                      
    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Failed to initialize security. Error code = 0x" 
            << hex << hres << endl;
        CoUninitialize();
		return 1;
		} else return 1;                    // Program has failed.
    } else return 0;
    
}
int GetInfo::InitLocatorWMI()
{
    hres = CoCreateInstance(
        CLSID_WbemLocator,             
        0, 
        CLSCTX_INPROC_SERVER, 
        IID_IWbemLocator, (LPVOID *) &pLoc);
 
    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Failed to create IWbemLocator object."
            << " Err code = 0x"
            << hex << hres << endl;
        CoUninitialize();
        return 1;   
		} else return 1;// Program has failed.
    } else return 0;
}
int GetInfo::ConnectToRoot(wstring pathOfWMINamespace)
{
hres = pLoc->ConnectServer(
	_bstr_t(pathOfWMINamespace.c_str()), // Object path of WMI namespace
         NULL,                    // User name. NULL = current user
         NULL,                    // User password. NULL = current
         0,                       // Locale. NULL indicates current
         NULL,                    // Security flags.
         0,                       // Authority (e.g. Kerberos)
         0,                       // Context object 
         &pSvc                    // pointer to IWbemServices proxy
         );
    
    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Could not connect. Error code = 0x" 
             << hex << hres << endl;
        pLoc->Release();     
        CoUninitialize();
        return 1;                // Program has failed.
		} else return 1;
    } else {
				if (_debug)
				{
					wcout << "Connected to "<< pathOfWMINamespace.c_str()<<" namespace" << endl;
					return 0;
				} else return 0;
			}


}
int GetInfo::SetProxyLevel()
{
    hres = CoSetProxyBlanket(
       pSvc,                        // Indicates the proxy to set
       RPC_C_AUTHN_WINNT,           // RPC_C_AUTHN_xxx
       RPC_C_AUTHZ_NONE,            // RPC_C_AUTHZ_xxx
       NULL,                        // Server principal name 
       RPC_C_AUTHN_LEVEL_CALL,      // RPC_C_AUTHN_LEVEL_xxx 
       RPC_C_IMP_LEVEL_IMPERSONATE, // RPC_C_IMP_LEVEL_xxx
       NULL,                        // client identity
       EOAC_NONE                    // proxy capabilities 
    );

    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Could not set proxy blanket. Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();     
        CoUninitialize();
        return 1;               // Program has failed.
		} else return 1;
    } else return 0;
}
int GetInfo::Query(string query)
{
    hres = pSvc->ExecQuery(
        bstr_t("WQL"), 
        bstr_t(query.c_str()),
        WBEM_FLAG_FORWARD_ONLY | WBEM_FLAG_RETURN_IMMEDIATELY, 
        NULL,
        &pEnumerator);
    
    if (FAILED(hres))
    {
		if (_debug)
		{
        cout << "Query for operating system name failed."
            << " Error code = 0x" 
            << hex << hres << endl;
        pSvc->Release();
        pLoc->Release();
        CoUninitialize();
        return 1;               // Program has failed.
		} else return 1;
	} else return 0;
}
int GetInfo::GetData(LPCWSTR attribute, IEnumWbemClassObject* pEnumerator)
{
	VariantClear(&vtProp);
    HRESULT hr = pEnumerator->Next(WBEM_INFINITE, 1, 
            &pclsObj, &uReturn);

        if(0 == uReturn)
        {
            return 0;
        }
		if(pclsObj == NULL)
		{
			if (_debug)
			{
				wcout<<"PclsObj is empty"<<endl;
				return 1;
			}
		}

		hr = pclsObj->Get(attribute, 0, &vtProp, 0, 0);

        pclsObj->Release();

	return 0;
}
int GetInfo::Cleanup()
{
	   pSvc->Release();
    pLoc->Release();
    pEnumerator->Release();
    pclsObj->Release();
    CoUninitialize();

	return 0;
}


std::wstring GetInfo::StringToWString(std::string& s)
{
std::wstring temp(s.length(),L' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}


std::string GetInfo::WStringToString(std::wstring& s)
{
std::string temp(s.length(), ' ');
std::copy(s.begin(), s.end(), temp.begin());
return temp;
}

int GetInfo::CMP()// info about Local host
{
		
	GetInfo::Query("SELECT * FROM Win32_ComputerSystem");
	GetInfo::GetData(L"Caption", GetInfo::GetEnumerator());
	oCMP.Hostname = vtProp.bstrVal;
	if (_debug)
		{
	wcout<<"Nazwa Komputera : "<<oCMP.Hostname<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_ComputerSystem");
	GetInfo::GetData(L"Workgroup", GetInfo::GetEnumerator());
	oCMP.Workgroup = GetInfo::vtProp.bstrVal;
	if (_debug)
		{
	wcout<<"Grupa robocza : "<<oCMP.Workgroup<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_ComputerSystem");
	GetInfo::GetData(L"Manufacturer", GetInfo::GetEnumerator());
	oCMP.Manufacturer = GetInfo::vtProp.bstrVal;
	if (_debug)
		{
	wcout<<"Producent plyty glownej: "<<oCMP.Manufacturer<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_ComputerSystem");
	GetInfo::GetData(L"Model", GetInfo::GetEnumerator());
	oCMP.Model = GetInfo::vtProp.bstrVal;
	if (_debug)
		{
	wcout<<"Model plyty glownej : "<<oCMP.Model<<endl;
	}


	GetInfo::Query("SELECT * FROM Win32_NetworkAdapterConfiguration");
	GetInfo::GetData(L"Caption", GetInfo::GetEnumerator());
	oCMP.Ip = GetInfo::vtProp.bstrVal[3];
	if (_debug)
		{
	wcout<<"Adres IP : "<<oCMP.Ip<<endl;
	}

	
	return 0;
}
int GetInfo::VCRD()// Video card
{
	//klasa Win32_VideoConfiguration 

	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"AdapterCompatibility", GetInfo::GetEnumerator());
	oVCRD.Producer = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
		wcout<<"Producent pamięci :"<<oVCRD.Producer<<endl; 
	}
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"Name", GetInfo::GetEnumerator());
	oVCRD.Model = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
		wcout<<"Model :"<<oVCRD.Model<<endl; 
	}
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"AdapterRAM", GetInfo::GetEnumerator());
	oVCRD.Ram = GetInfo::vtProp.uintVal/1024/1024;
	if (_debug)
	{
		wcout<<"Ilość pamięci :"<<oVCRD.Ram<<" MB"<<endl;
	}
	
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"CurrentHorizontalResolution", GetInfo::GetEnumerator());
	oVCRD.h = GetInfo::vtProp.uintVal;
	if (_debug)
	{
		wcout<<"Rozdzielczość : "<<oVCRD.h<<" x ";
	}
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"CurrentVerticalResolution", GetInfo::GetEnumerator());
	oVCRD.v = GetInfo::vtProp.uintVal;
	if (_debug)
	{
		wcout<<oVCRD.v<<" : ";
	}
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"CurrentBitsPerPixel", GetInfo::GetEnumerator());
	oVCRD.bpp = GetInfo::vtProp.uintVal;
	if (_debug)
	{
		wcout<<oVCRD.bpp<<" bpp @ ";
	}
	GetInfo::Query("SELECT * FROM Win32_VideoController");
	GetInfo::GetData(L"CurrentRefreshRate", GetInfo::GetEnumerator());
	oVCRD.refresh = GetInfo::vtProp.uintVal;
	if (_debug)
	{
	wcout<<oVCRD.refresh<<endl;
	}
	
	return 0;
}

int GetInfo::VRam() // ram
{
	GetInfo::Query("SELECT * FROM Win32_PhysicalMemoryArray");
	GetInfo::GetData(L"MaxCapacity", GetInfo::GetEnumerator());
	oVRam.Capacity = GetInfo::vtProp.uintVal/1024;
	if (_debug)
		{
	wcout<<"Pamiec RAM :"<<oVRam.Capacity<<endl;
	}
	return 0;
}
int GetInfo::CPU()// cpu
{ 
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"Name", GetInfo::GetEnumerator());
	oCPU.Manufacturer = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
	wcout<<"Model :"<<oCPU.Manufacturer<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"NumberOfCores", GetInfo::GetEnumerator());
	oCPU.NumberOfCore = GetInfo::vtProp.uintVal;
	if (_debug)
	{
	wcout<<"Liczba rdzeni :"<<oCPU.NumberOfCore<<endl;
	}

	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"CurrentClockSpeed", GetInfo::GetEnumerator());
	oCPU.CurrentClockSpeed = (float)GetInfo::vtProp.uintVal / 10000;
	if (_debug)
	{
	wcout<<"Taktowanie zegara:"<<oCPU.CurrentClockSpeed <<"GHz"<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"ExtClock", GetInfo::GetEnumerator());
	oCPU.ExtClock = (float)GetInfo::vtProp.uintVal;
	if (_debug)
	{
	wcout<<"Taktowanie szyny FSB  :"<<oCPU.ExtClock<<" MHz"<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"CurrentVoltage", GetInfo::GetEnumerator());
	oCPU.CurrentVoltage = (float)GetInfo::vtProp.uintVal / 10;
	if (_debug)
	{
	wcout<<"Napięcie  :"<<oCPU.CurrentVoltage<<"x 10" <<endl;
	}

	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"LoadPercentage", GetInfo::GetEnumerator());
	oCPU.LoadPercentage = GetInfo::vtProp.uintVal;
	
	if (_debug)
	{
		wcout<<"Uzycie :"<<oCPU.LoadPercentage <<" %"<<endl;
	}
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"SocketDesignation", GetInfo::GetEnumerator());
	oCPU.SocketDesignation = GetInfo::vtProp.bstrVal;
	
	if (_debug)
	{
		wcout<<"Typ podstawki :"<<oCPU.SocketDesignation<<endl;
	}
	return 0;
}
int GetInfo::IOS()// operating system
{ 

	GetInfo::Query("SELECT * FROM Win32_OperatingSystem");
	GetInfo::GetData(L"Caption", GetInfo::GetEnumerator());
	oIOS.productName = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
		wcout<<"System Operacyjny :"<<GetInfo::vtProp.bstrVal<<endl;
	}

	GetInfo::Query("SELECT * FROM Win32_OperatingSystem");
	GetInfo::GetData(L"OSArchitecture", GetInfo::GetEnumerator());
	oIOS.OsArchitecture = GetInfo::vtProp.bstrVal;
	
	if (_debug)
	{
		wcout<<"Architektura :"<<oIOS.OsArchitecture<<endl;
	}




	return 0;
}
int GetInfo::HDD()
{
	
	GetInfo::Query("SELECT * FROM Win32_DiskDrive");
	GetInfo::GetData(L"InterfaceType", GetInfo::GetEnumerator());
	oHDD.Interface = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
		wcout<<"Interfejs dysku :"<<oHDD.Interface<<endl;
	}

	

	GetInfo::Query("SELECT * FROM Win32_DiskDrive");
	GetInfo::GetData(L"Model", GetInfo::GetEnumerator());
	oHDD.Model = GetInfo::vtProp.bstrVal;
	if (_debug)
	{
		wcout<<"Model dysku : "<<oHDD.Model<<endl;
	}

	GetInfo::Query("SELECT * FROM Win32_DiskDrive");
	GetInfo::GetData(L"Partitions", GetInfo::GetEnumerator());
	oHDD.Partitions = GetInfo::vtProp.uintVal;
	if (_debug)
	{
		wcout<<"Ilość partycji : "<<oHDD.Partitions<<endl;
	}



	

	return 0;
}




unsigned int GetInfo::CPUUssage()
{
	GetInfo::Query("SELECT * FROM Win32_Processor");
	GetInfo::GetData(L"LoadPercentage", GetInfo::GetEnumerator());
	return GetInfo::vtProp.uintVal;
	
}
